package Demo;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2022-11-29
 * Time: 11:11
 */
public class Thread_Demo5 {
    /**
     * 写一个死锁(线程1拥有锁1并尝试获取锁2, 线程2拥有锁2并尝试获取锁1);
     * @param args
     */

    public static void main(String[] args) {
        //创建锁对象
        Object lock1 = new Object();
        Object lock2 = new Object();

        // 创建线程
        Thread t1 = new Thread(() -> {
            synchronized (lock1) {
                try {
                    // 休眠确保 t1 获取到lock1
                    Thread.sleep(1000);
                    System.out.println("只获取了lock1一把锁!");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 此时由于t2线程已经对lock2加锁并未释放, t1想获取lock2锁,必须等待t2对lock2进行释放
                synchronized (lock2) {
                    System.out.println("先获取lock1再获取lock2都获取到了!");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                try {
                    // 休眠确保 t2 获取到lock2
                    Thread.sleep(1000);
                    System.out.println("只获取了lock2一把锁!");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 此时由于t1线程已经对lock1加锁并未释放, t2想获取lock1锁, 必须等待t1对lock1进行释放
                synchronized (lock1) {
                    System.out.println("先获取lock2在获取lock1都获取到了!");
                }
            }
        });

        t1.start();
        t2.start();
        // 调用 jconsole 观察
    }

    // 解决死锁问题  -- 打破锁循环(人为规定顺序)

    public static void main1(String[] args) {
        //创建锁对象
        Object lock1 = new Object();
        Object lock2 = new Object();

        // 创建线程
        Thread t1 = new Thread(() -> {
            while(true) {
                synchronized (lock1) {
                        System.out.println("只获取了lock1一把锁!");
                    synchronized (lock2) {
                        System.out.println("先获取lock1再获取lock2都获取到了!");
                    }
                }
            }
        });
        // 此时t1 t2 发生锁竞争 竞争同一把锁lock1  谁先获取到 谁就先执行 另一个线程进行阻塞等待,
        // 当先获取到lock1得释放锁后,再次竞争 谁先获得就执行谁
        Thread t2 = new Thread(() -> {
            while(true) {
                synchronized (lock1) {
                        System.out.println("只获取了lock2一把锁!");
                    synchronized (lock2) {
                        System.out.println("先获取lock1在获取lock2都获取到了!");
                    }
                }
            }
        });

        t1.start();
        t2.start();
        // 调用 jconsole 观察
    }

}
